package com.suoluo.zenadmin.service.dest;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.multipart.MultipartFile;

import com.suoluo.zenadmin.common.CommonResp;
import com.suoluo.zenadmin.common.config.SystemConfigHolder;
import com.suoluo.zenadmin.dao.dest.DestFeatureCategoryDAO;
import com.suoluo.zenadmin.oss.OSSService;
import com.suoluo.zenadmin.oss.OSSService.OSSImageException;
import com.suoluo.zenadmin.service.ServiceException;
import com.suoluo.zenadmin.vo.dest.DestFeatureCategoryVO;

public class DestFeatureCategoryServiceImpl implements DestFeatureCategoryService{

	@Autowired
	private DestFeatureCategoryDAO categoryDAO;
	@Resource(name = "ossService")
	private OSSService ossService;
	
	private final Map<Integer,DestFeatureCategoryVO> categoryCache = new HashMap<Integer, DestFeatureCategoryVO>();
	
//	private List<DestFeatureCategoryVO> category
	
	private final Object lock = new Object();
public DestFeatureCategoryVO category;
	
	public void initCache() {
		synchronized (lock) {
			categoryCache.clear();
			List<DestFeatureCategoryVO> categoryList = categoryDAO
					.findAllCategory();
			for (DestFeatureCategoryVO category : categoryList) {
				categoryCache.put(category.getFeatureCategoryId(), new CategoryWrapper(category));
			}

			// 关联父类别名称
			for (DestFeatureCategoryVO category : categoryList) {
				DestFeatureCategoryVO parent = categoryCache.get(category
						.getFeatureParentCategoryId());
				if (parent != null) {
					//category.setParentName(parent.getFeatureCategoryName());
					categoryCache.get(category.getFeatureCategoryId()).setParentName(parent.getFeatureCategoryName());
				}
			}
		}
	}
	
	private void addCache(DestFeatureCategoryVO category){
		synchronized (lock) {
			categoryCache.put(category.getFeatureCategoryId(), new CategoryWrapper(category));
		}
	}
	
	private List<DestFeatureCategoryVO> listCache(){
		synchronized (lock) {
			return new ArrayList<DestFeatureCategoryVO>(categoryCache.values());
		}
	}
	
	private DestFeatureCategoryVO getCache(int featureCategoryId){
		synchronized (lock) {
			return categoryCache.get(featureCategoryId);
		}
	}
	
	/**
	 * 查询根类别，过滤掉指定ID的跟类别
	 * @param id
	 * @return
	 */
	private List<DestFeatureCategoryVO> listRootViewableWithoutId(int id){
		List<DestFeatureCategoryVO> result = new ArrayList<DestFeatureCategoryVO>();
		synchronized (lock) {
			for (DestFeatureCategoryVO category : categoryCache.values()){
				int cid = category.getFeatureCategoryId();
				int cpid = category.getFeatureParentCategoryId();
				if (cpid == 0 && category.getRootViewable() == 1 && cid != id){
					result.add(category);
				}
			}
		}
		Collections.sort(result);
		return result;
	}
	
	private void deleteCache(int id){
		synchronized (lock) {
			categoryCache.remove(id);
		}
	}
	
	private void updateCache(DestFeatureCategoryVO category){
		synchronized (lock) {
			// 如果是特别体验
			int categoryId = category.getFeatureCategoryId();
			
			CategoryWrapper categoryWrapper = (CategoryWrapper) categoryCache.get(categoryId);
			if (categoryId == 5) {
				categoryWrapper.setCategorySpecail(category);
			} else {
				// 判断顺序是否更改
				int oldOrder = category.getOldOrder();
				int newOrder = category.getFeatureCategoryOrder();
				if (oldOrder != newOrder) {
					// 将类别修改前的顺序替换修改后的顺序
					categoryDAO.updateFeatureCategoryByOrderId(category);
					for (DestFeatureCategoryVO c : categoryCache.values()){
						//将以前的该顺序的类别替换成当前被更新的类别的以前的顺序
						if (c.getFeatureCategoryOrder() == category.getFeatureCategoryOrder()){
							CategoryWrapper cw = (CategoryWrapper)c;
							
							cw.setFeatureCategoryOrder(category.getOldOrder());
						}
					}
				}
//				categoryDAO.updateDestFeatureCategory(category);
				//更新该类别的缓存和父类别名称
				DestFeatureCategoryVO parentCategory = categoryCache.get(category.getFeatureParentCategoryId());
				if (parentCategory != null){
					//categoryWrapper.setParentName(parentCategory.getFeatureCategoryName());
					category.setParentName(parentCategory.getFeatureCategoryName());
				}
				categoryWrapper.setCategory(category);
			}
		}
	}
	
//	private static class DestFeatureCategorySorter implements Comparator<DestFeatureCategoryVO>{
//		@Override
//		public int compare(DestFeatureCategoryVO o1, DestFeatureCategoryVO o2) {
//			return o1.getFeatureCategoryOrder() - o2.getFeatureCategoryOrder();
//		}
//	}
	
	@Override
	public List<DestFeatureCategoryVO> findListDestFeatureCategory() {
		List<DestFeatureCategoryVO> categoryList = listCache();
		Collections.sort(categoryList);
		return categoryList;
	}
	
	
	@Override
	public void saveDestFeatureCategory(DestFeatureCategoryVO category) {
		String imageName = null;
		try {
			MultipartFile mfile = category.getMfile();
			if (mfile != null && !mfile.isEmpty()) {
				imageName = ossService.putImage(mfile);
			}
			category.setFeatureCategoryOrigImg(imageName);
			Integer maxOrder = categoryDAO.findFeatureCategoryMaxOrder();
			if (maxOrder == null) {
				maxOrder = 1;
			} else {
				maxOrder = maxOrder + 1;
			}
			category.setFeatureCategoryOrder(maxOrder);
			int featureCategoryId = categoryDAO.saveDestFeatureCategory(category);
			category.setFeatureCategoryId(featureCategoryId);
			
			//添加到缓存中
			DestFeatureCategoryVO parent = getCache(category.getFeatureParentCategoryId());
			if (parent != null){
				category.setParentName(parent.getFeatureCategoryName());
			}
			addCache(category);
		} catch (OSSImageException e) {
			throw new ServiceException(CommonResp.FAIL_CODE, "图片保存失败！", e);
		} catch (Exception e) {
			ossService.deleteImage(imageName);
			throw new ServiceException(CommonResp.FAIL_CODE, "目的地特色类别保存失败！", e);
		}

	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public DestFeatureCategoryVO findDestFeatureCategoryById(int categoryId) {
		return getCache(categoryId);
	}
	
	

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<DestFeatureCategoryVO> findRootCategoryWithoutExperience() {
		return listRootViewableWithoutId(SystemConfigHolder.getDestFeatureCategorySpecial());
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void updateDestFeatureCategory(DestFeatureCategoryVO category) {
		int categoryId = category.getFeatureCategoryId();
		String imageName = null;
		try {

			String categoryImg = category.getFeatureCategoryOrigImg();
			MultipartFile file = category.getMfile();
			if (file != null && !file.isEmpty()) {
				imageName = ossService.updateImage(file, categoryImg);
				category.setFeatureCategoryOrigImg(imageName);
			}
			// 如果是特别体验
			if (categoryId == 5) {
				categoryDAO.updateSpecialCategory(category);
			} else {
				// 判断顺序是否更改
				int oldOrder = category.getOldOrder();
				int newOrder = category.getFeatureCategoryOrder();
				if (oldOrder != newOrder) {
					// 将类别修改前的顺序替换修改后的顺序
					categoryDAO.updateFeatureCategoryByOrderId(category);
				}
				categoryDAO.updateDestFeatureCategory(category);
			}
			
			//更新缓存
			updateCache(category);
		} catch (OSSImageException e) {
			throw new ServiceException(CommonResp.FAIL_CODE, "图片修改失败！", e);
		} catch (Exception e) {
			ossService.deleteImage(imageName);
			throw new ServiceException(CommonResp.FAIL_CODE, "目的地特色类别保存失败！");
		}

	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void deleteDestFeatureCategory(DestFeatureCategoryVO categoryVO) {
		int categoryId = categoryVO.getFeatureCategoryId();
		// 判断该类别是否已被目的地特色引用
		int feature = categoryDAO.findDestFeatureCountByCategoryId(categoryId);
		// 如果类别被引用，则不可以删除
		if (feature > 0) {
			throw new ServiceException(CommonResp.FAIL_CODE, "该特色类别已被目的地特色引用，不可以删除！");
		}
		//判断类别是否被首页引用
		int home = categoryDAO.findHomeCountByCategoryId(categoryId);
		// 如果类别被引用，则不可以删除
		if (home > 0) {
			throw new ServiceException(CommonResp.FAIL_CODE, "该特色类别已被首页类别引用，不可以删除！");
		}
		//是否是父类别
		int parent = categoryDAO.findParentCategoryCountByCategoryId(categoryId);
		// 如果类别被引用，则不可以删除
		if (parent > 0) {
			throw new ServiceException(CommonResp.FAIL_CODE, "该父类别有子类别引用，不可以删除！");
		}
		//是否被特色项引用
		int item = categoryDAO.findDestFeatureItemCountByCategoryId(categoryId);
		// 如果类别被引用，则不可以删除
		if (item > 0) {
			throw new ServiceException(CommonResp.FAIL_CODE, "该类别被目的地特色项引用，不可以删除！");
		}
		//是否被风格偏好首页引用
		int style = categoryDAO.findStyleCountByCategoryId(categoryId);
		// 如果类别被引用，则不可以删除
		if (style > 0) {
			throw new ServiceException(CommonResp.FAIL_CODE, "该特色类别已被风格偏好首页引用，不可以删除！");
		}
		String imgPath = categoryVO.getFeatureCategoryOrigImg();
		ossService.deleteImage(imgPath);

		categoryDAO.deleteDestFeatureCategory(categoryId);
		
		//移除缓存
		deleteCache(categoryId);
	}
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<DestFeatureCategoryVO> findRootCategoryWithoutHotel() {
		int hotelCategory = SystemConfigHolder.getDestFeatureHotelCategoryId();
//		return categoryDAO.findRootCategoryWithoutId(hotelCategory);
		return listRootViewableWithoutId(hotelCategory);
	}
	
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<DestFeatureCategoryVO> findAllCategory() {
		List<DestFeatureCategoryVO> list = categoryDAO.findAllCategory();
//		List<DestFeatureCategoryVO> list = listCache();
		list = changeCategoryDesc(list);
		return list;
	}
	
	
	/**
	 * 目的地添加特色类别时 父类别和子类别需要区分，子类别名称前面加上--
	 * 
	 * @param data
	 * @return
	 */
	private List<DestFeatureCategoryVO> changeCategoryDesc(
			List<DestFeatureCategoryVO> data) {
		List<DestFeatureCategoryVO> resList = new ArrayList<DestFeatureCategoryVO>();
		for (DestFeatureCategoryVO destFeatureCategory : data) {
			if (destFeatureCategory.getFeatureParentCategoryId() == 0) {
				resList.add(destFeatureCategory);
				for (DestFeatureCategoryVO category : data) {
					if (category.getFeatureParentCategoryId() == destFeatureCategory
							.getFeatureCategoryId()) {
						String name = "--" + category.getFeatureCategoryName();
						category.setFeatureCategoryName(name);
						resList.add(category);
					}
				}
			}
			
		}
		return resList;
	}
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<DestFeatureCategoryVO> findAllRootCategory() {
		//查询所有的父类别，并且父类别是可见的
//		return categoryDAO.findRootCategoryWithoutId(0);
		return listRootViewableWithoutId(0);
	}
	
	@Override
	public List<DestFeatureCategoryVO> findAllLeafCategory() {
		List<DestFeatureCategoryVO> result = new ArrayList<DestFeatureCategoryVO>();
		synchronized (lock) {
			for (DestFeatureCategoryVO category : categoryCache.values()){
				int cid = category.getFeatureCategoryId();
				if (cid == SystemConfigHolder.getDestFeatureCategorySpecial()){
					continue;
				}
				int cpid = category.getFeatureParentCategoryId();
				if (cpid != 0 || category.getRootViewable() == 0){
					result.add(category);
				}
			}
		}
		Collections.sort(result);
		return result;
	}
	
	static class CategoryWrapper extends DestFeatureCategoryVO{
//		/**
//		 * 特色类别标识
//		 */
//		int featureCategoryId;
//		/**
//		 * 特色类别名称
//		 */
//		String featureCategoryName;
//		/**
//		 * 分类顺序
//		 */
//		int featureCategoryOrder;
//		/**
//		 * 该字段父类别为null,如果是子类别则是t_feature_category_id
//		 */
//		int featureParentCategoryId;
//
//		/**
//		 * 特色类别颜色
//		 */
//		String featureCategoryColor;
//		/**
//		 * 特色类别描述
//		 */
//		String featureCategoryDesc;
//		/**
//		 * 默认停留时间
//		 */
//		int defaultPauseTime;
//		/**
//		 * 图片迁移的路径
//		 */
//		String featureCategoryOrigImg;
//		/**
//		 * 是否是顶层类别
//		 */
//		int rootViewable;
//		
//		/**
//		 * 归属父类名称
//		 */
//		String parentName;

		public CategoryWrapper(DestFeatureCategoryVO category) {
			setCategory(category);
		}

		public void setCategory(DestFeatureCategoryVO category){
			super.setFeatureCategoryId(category.getFeatureCategoryId());
			super.setFeatureCategoryName(category.getFeatureCategoryName());
			super.setFeatureCategoryOrder(category.getFeatureCategoryOrder());
			super.setFeatureParentCategoryId(category.getFeatureParentCategoryId());
			super.setFeatureCategoryColor(category.getFeatureCategoryColor());
			super.setFeatureCategoryDesc(category.getFeatureCategoryDesc());
			super.setDefaultPauseTime(category.getDefaultPauseTime());
			super.setFeatureCategoryOrigImg(category.getFeatureCategoryOrigImg());
			super.setRootViewable(category.getRootViewable());
			super.setParentName(category.getParentName());
		}
		
		public void setCategorySpecail(DestFeatureCategoryVO category) {
			super.setFeatureCategoryColor(category.getFeatureCategoryColor());
			super.setFeatureCategoryDesc(category.getFeatureCategoryDesc());
			super.setDefaultPauseTime(category.getDefaultPauseTime());
			super.setFeatureCategoryOrigImg(category.getFeatureCategoryOrigImg());
		}
		
		@Override
		public void setFeatureCategoryOrder(int categoryOrder) {
			super.setFeatureCategoryOrder(categoryOrder);
		}
		
		@Override
		public String getParentName() {
			return super.getParentName();
		}

		@Override
		public void setParentName(String parentName) {
			super.setParentName(parentName);
		}

		@Override
		public int getFeatureCategoryId() {
			return super.getFeatureCategoryId();
		}

		@Override
		public void setFeatureCategoryId(int featureCategoryId) {
			throw new AbstractMethodError();
		}

		@Override
		public String getFeatureCategoryName() {
			return super.getFeatureCategoryName();
		}

		@Override
		public void setFeatureCategoryName(String featureCategoryName) {
			throw new AbstractMethodError();
		}

		@Override
		public int getFeatureCategoryOrder() {
			return super.getFeatureCategoryOrder();
		}
//
//		@Override
//		public void setFeatureCategoryOrder(int featureCategoryOrder) {
//			throw new AbstractMethodError();
//		}

		@Override
		public int getFeatureParentCategoryId() {
			return super.getFeatureParentCategoryId();
		}

		@Override
		public void setFeatureParentCategoryId(int featureParentCategoryId) {
			throw new AbstractMethodError();
		}

		@Override
		public String getFeatureCategoryColor() {
			return super.getFeatureCategoryColor();
		}

		@Override
		public void setFeatureCategoryColor(String featureCategoryColor) {
			throw new AbstractMethodError();
		}

		@Override
		public String getFeatureCategoryDesc() {
			return super.getFeatureCategoryDesc();
		}

		@Override
		public void setFeatureCategoryDesc(String featureCategoryDesc) {
			throw new AbstractMethodError();
		}

		@Override
		public int getDefaultPauseTime() {
			return super.getDefaultPauseTime();
		}

		@Override
		public void setDefaultPauseTime(int defaultPauseTime) {
			throw new AbstractMethodError();
		}

		@Override
		public String getFeatureCategoryOrigImg() {
			return super.getFeatureCategoryOrigImg();
		}

		@Override
		public void setFeatureCategoryOrigImg(String featureCategoryOrigImg) {
			throw new AbstractMethodError();
		}

		@Override
		public int getRootViewable() {
			return super.getRootViewable();
		}

		@Override
		public void setRootViewable(int rootViewable) {
			throw new AbstractMethodError();
		}
	}
}
